﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Money.Interfaces;
using Money.Data;
using One.Framework;
using One.Framework.Security;

namespace Money.Services
{
    public class UserService : IUserService
    {
        private MoneyManagerDataContext context;

        public UserService()
        {
            context = new MoneyManagerDataContext();
        }

        public void CreateUser(Money.Data.User item)
        {
            try
            {
                context.Users.InsertOnSubmit(item);
                context.SubmitChanges();
            }
            catch(Exception ex)
            {
                Logger.Error(ex.ToString());
                throw new Exception("Cannot create user");
            }
        }

        public void DeleteUser(int id)
        {
            try
            {
                User item = GetUserById(id);
                context.Users.DeleteOnSubmit(item);
                context.SubmitChanges();
            }
            catch (Exception ex)
            {
                Logger.Error(ex.ToString());
                throw new Exception("Cannot delete user");
            }
        }

        public void UpdateUser(Money.Data.User item)
        {
            try
            {
                context.SubmitChanges();
            }
            catch (Exception ex)
            {
                Logger.Error(ex.ToString());
                throw new Exception("Cannot update user");
            }
        }

        public Money.Data.User Authentication(string username, string password)
        {
            try
            {
                return context.Users.Where(u => u.Username == username && u.Password == EncryptUtility.HashMD5(password)).SingleOrDefault<User>();
            }
            catch (Exception ex)
            {
                Logger.Error(ex.ToString());
                throw new Exception("Cannot get user");
            }
        }

        public User GetUserById(int id)
        {
            try
            {
                return context.Users.Where(u => u.UserId == id).SingleOrDefault<User>();
            }
            catch (Exception ex)
            {
                Logger.Error(ex.ToString());
                throw new Exception("Cannot get user");
            }
        }

        public List<User> GetUsers(string orderBy, string orderDirection, int page, int pageSize, out int totalRecords)
        {
            try
            {
                var query = from u in context.Users
                            select u;
                return query.OrderByPaging<User>(orderBy, orderDirection, page, pageSize, out totalRecords).ToList<User>();
            }
            catch (Exception ex)
            {
                Logger.Error(ex.ToString());
                throw new Exception("Cannot get users");
            }
        }

        public User GetUserByUsername(string username)
        {
            try
            {
                return context.Users.Where(u => u.Username == username).SingleOrDefault<User>();
            }
            catch (Exception ex)
            {
                Logger.Error(ex.ToString());
                throw new Exception("Cannot get user");
            }
        }

        public User GetUserByEmail(string email)
        {
            try
            {
                return context.Users.Where(u => u.Email == email).SingleOrDefault<User>();
            }
            catch (Exception ex)
            {
                Logger.Error(ex.ToString());
                throw new Exception("Cannot get user");
            }
        }

        public bool CanDelete(int id)
        {
            User item = GetUserById(id);
            if(item != null)
                if (item.Accounts.Count > 0)
                    return false;
            return true;
        }
    }
}
